from os import name
from flask import request
from models.order import Order
from models.store import Store
from models.user_store import UserStore
from models.user import User
from extensions import db
from utils.auth import token_required
from flask_restx import Namespace, Resource, fields
import uuid
from models.product import Product
from models.order_staff import OrderStaff
import uuid
from models.card_package import CardPackage
from models.card_consumption import CardConsumption
from datetime import datetime

api = Namespace('orders', description='订单管理相关接口')

# 定义API模型
order_item_model = api.model('OrderItem', {
    'service_name': fields.String(required=True, description='服务名称'),
    'price': fields.Float(required=True, description='服务价格'),
    'staff_id': fields.String(required=True, description='服务人员ID')
})

order_model = api.model('Order', {
    'order_id': fields.String,
        'store_id': fields.String,
        'customer_id': fields.String,
        'items': fields.List(fields.Nested(order_item_model)),
        'total_amount': fields.Float,
        'status': fields.String,
        'payment_method': fields.String,
        'remarks': fields.String,
        'created_at': fields.DateTime,
        'updated_at': fields.DateTime,
        'actual_amount': fields.Float,
        'created_at': fields.DateTime,
        'updated_at': fields.DateTime,
        'total_amount':fields.Float,
        'card_package': fields.Nested(api.model('CardPackages', {
            'package_id':fields.String,
            'card_type':fields.String,
            'name':fields.String,
        })),
 
        'phone': fields.String(description='客户手机号(可选)'),
        'store': fields.Nested(api.model('StoreInfo', {
            'store_id': fields.String,
            'name': fields.String,
            'address': fields.String
        })),
        'customer': fields.Nested(api.model('CustomerInfo', {
            'name': fields.String,
            'phone': fields.String
        }))
})

base_response = api.model('BaseResponse', {
    'status': fields.String(description='响应状态'),
    'message': fields.String(description='响应消息')
})

order_detail_response = api.inherit('OrderDetailResponse', base_response, {
    'data': fields.Nested(api.model('OrderDetail', {
        'order_id': fields.String,
        'store_id': fields.String,
        'customer_id': fields.String,
        'items': fields.List(fields.Nested(order_item_model)),
        'total_amount': fields.Float,
        'status': fields.String,
        'payment_method': fields.String,
        'remarks': fields.String,
        'created_at': fields.DateTime,
        'updated_at': fields.DateTime,
        'actual_amount': fields.Float,
        'phone': fields.String(description='客户手机号(可选)'),
        'created_at': fields.DateTime,
        'updated_at': fields.DateTime,
        'total_amount':fields.Float,
        'store': fields.Nested(api.model('StoreInfo', {
            'store_id': fields.String,
            'name': fields.String,
            'address': fields.String
        })),
        'customer': fields.Nested(api.model('CustomerInfo', {
            'name': fields.String,
            'phone': fields.String
        }))
    }))
})

order_response = api.model('BaseResponse', {
    'status': fields.String(description='响应状态'),
    'message': fields.String(description='响应消息'),
    'data': fields.Nested(api.model('OrderList', {
        'list': fields.List(fields.Nested(order_model)),
        'total': fields.Integer
    }))
})

@api.route('', strict_slashes=False)
class OrderList(Resource):
    @api.doc('获取所有订单列表', params={
        'start_time': '开始时间(格式: YYYY-MM-DD)(可选)',
        'end_time': '结束时间(格式: YYYY-MM-DD)(可选)',
        'store_id': '店铺ID(可选)',
        'search_key': '搜索关键字(可选)',
        'customer_id': '顾客ID(可选)',
        'page_num': '页码(可选)',
        'page_size': '每页数量(可选)'
    })
    @api.marshal_with(order_response)
    @token_required
    def get(self):
        """获取所有订单列表"""
        start_time = request.args.get('start_time')
        end_time = request.args.get('end_time')
        store_id = request.args.get('store_id')
        customer_id = request.args.get('customer_id')
        page_num = request.args.get('page_num', type=int)
        page_size = request.args.get('page_size', type=int)
        search_key = request.args.get('search_key')
        
        query = db.session.query(
            Order,
            Store,
            User.name.label('customer_name'),
            User.phone.label('customer_phone'),
            CardPackage  # 添加卡包查询
        ).join(
            Store,
            Order.store_id == Store.store_id
        ).join(
            User,
            Order.customer_id == User.user_id
        ).outerjoin(  # 使用左连接，因为卡包是可选的
            CardPackage,
            Order.card_package_id == CardPackage.package_id
        ).filter(
            Order.is_deleted == False
        )
        
        # 添加过滤条件
        if start_time:
            query = query.filter(Order.created_at >= start_time)
        if end_time:
            query = query.filter(Order.created_at <= end_time)
        if store_id:
            query = query.filter(Order.store_id == store_id)
        if customer_id:
            query = query.filter(Order.customer_id == customer_id)
        if search_key:
            query = query.filter(
                db.or_(
                    Order.phone.like(f'%{search_key}%'),
                    User.phone.like(f'%{search_key}%')
                )
            )
            
        total = query.count()  # 获取总条数
        query = query.order_by(db.desc(Order.id))  # 先排序
        
        # 添加分页
        if page_num and page_size:
            query = query.offset((page_num - 1) * page_size).limit(page_size)
            
        orders = query.all()  # 最后执行查询
        
        result = []
        for order, store, customer_name, customer_phone, card_package in orders:
            order_data = order.to_dict()
            order_data['store'] = store.to_dict()
            order_data['customer'] = {
                'name': customer_name,
                'phone': customer_phone
            }
            if card_package:  # 如果有卡包信息，添加到返回数据
                order_data['card_package'] = {
                    'package_id': card_package.package_id,
                    'name': card_package.name,
                    'card_type': card_package.card_type
                }
            result.append(order_data)
        
        return {
            'status': 'success',
            'data': {
                'list':result,
                'total': total
            }
        }, 200

@api.route('/<order_id>')
class OrderResource(Resource):
    @api.doc('获取单个订单信息')
    @api.marshal_with(order_detail_response)
    @token_required
    def get(self, order_id):
        """获取单个订单信息"""
        result = db.session.query(
            Order,
            Store,
            User.name.label('customer_name'),
            User.phone.label('customer_phone')
        ).join(
            Store,
            Order.store_id == Store.store_id
        ).join(
            User,
            Order.customer_id == User.user_id
        ).filter(
            Order.order_id == order_id,
            Order.is_deleted == False
        ).first()
        
        if not result:
            return {
                'status': 'error',
                'message': '订单不存在'
            }, 404
        
        if not result:
            db.session.rollback()
            return {
                'status': 'error',
                'message': '订单创建失败，请检查店铺和用户信息'
            }, 500

        order, store, customer_name, customer_phone = result
        order_data = order.to_dict()
        order_data['store'] = store.to_dict()
        order_data['customer'] = {
            'name': customer_name,
            'phone': customer_phone
        }
        
        return {
            'status': 'success',
            'data': order_data
        }, 200

@api.route('', strict_slashes=False)
class OrderCreate(Resource):
    @api.doc('创建新订单')
    @api.expect(order_model)
    @api.marshal_with(order_detail_response)
    @token_required
    def post(self):
        """创建新订单"""
        data = request.get_json()
        
        # 检查必填字段
        required_fields = ['store_id', 'customer_id', 'items', 'total_amount']
        for field in required_fields:
            if field not in data:
                return {
                    'status': 'error',
                    'message': f'缺少必填字段: {field}'
                }, 400

        try:
            # 预先获取所有需要的数据
            store = Store.query.filter_by(store_id=data['store_id']).first()
            if not store:
                return {'status': 'error', 'message': '店铺不存在'}, 400

            user = User.query.filter_by(user_id=data['customer_id']).first()
            if not user:
                return {'status': 'error', 'message': '用户不存在'}, 400
            
            staff = User.query.filter_by(user_id=data['staff_id']).first()
            if not staff:
                return {'status': 'error', 'message': '员工不存在'}, 400

            # 验证items格式并预先获取所有产品信息
            if not isinstance(data['items'], list):
                return {'status': 'error', 'message': 'items必须是列表格式'}, 400
            
            products = {}
            for product_id in data['items']:
                product = Product.query.filter_by(
                    product_id=product_id,
                    is_deleted=False
                ).first()
                if not product:
                    return {'status': 'error', 'message': f'商品不存在: {product_id}'}, 400
                products[product_id] = product

            # 验证卡包
            if (not data.get('card_package_id')):
                return {'status': 'error', 'message': '卡包不存在或已失效'}, 400
            card_package =  CardPackage.query.filter_by(
                    package_id=data['card_package_id'],
                    user_id=data['customer_id'],
                    is_deleted=False
                ).first()
            if not card_package:
                return {'status': 'error', 'message': '卡包不存在或已失效'}, 400
            
            if card_package.card_type == 'per_use':
                if card_package.remaining_amount < 1:
                        return {
                            'status': 'error',
                            'message': f'卡包次数不足，当前剩余: {card_package.remaining_amount}次，需要: 至少1次'
                        }, 400
            elif card_package.card_type == 'comprehensive' :
                    # 计算综合卡或默认卡(会员卡支付)消费金额
                    base_total_price = sum(products[item_id].price for item_id in data['items'])
                    total_price = base_total_price * (card_package.discount_rate or 1)
                    
                    if card_package.remaining_amount < total_price:
                        return {
                            'status': 'error',
                            'message': f'卡包余额不足，当前余额: ¥{card_package.remaining_amount}，需要: ¥{total_price}'
                        }, 400
            elif  card_package.card_type == 'default' and data.get('payment_method') == 'card':
                    # 计算综合卡或默认卡(会员卡支付)消费金额
                    base_total_price = sum(products[item_id].price for item_id in data['items'])
                    total_price = base_total_price * (card_package.discount_rate or 1)
                    if card_package.remaining_amount < total_price:
                        return {
                            'status': 'error',
                            'message': f'默认卡包余额不足，当前余额: ¥{card_package.remaining_amount}，需要: ¥{total_price}'
                        }, 400
                # 默认卡包选择现金，微信，支付包之类不需要进行余额校验
            
             # 计算基础总价和实际支付金额
            base_total_price = sum(products[item_id].price for item_id in data['items'])
            total_price = base_total_price  # 默认使用原价
            actual_amount = total_price * (card_package.discount_rate or 1) if card_package else total_price


            # 创建新订单
            new_order = Order(
                order_id=str(uuid.uuid4()),
                store_id=data['store_id'],
                customer_id=data['customer_id'],
                items=data['items'],
                total_amount=total_price,
                actual_amount=actual_amount,
                status=data.get('status', 'pending'),
                phone=user.phone ,
                payment_method=data.get('payment_method'),
                remarks=data.get('remarks'),
                card_package_id=data.get('card_package_id')  # 添加卡包ID
            )
            db.session.add(new_order)

            # 创建消费记录
            for product_id in data['items']:
                product = products[product_id]  # 使用预先查询的产品信息
                transactions = _calculate_transaction_details(payment_method=data.get('payment_method'),
                    customer=user,
                    product=product,
                    card_package=card_package,
                    staff=staff
                )
                
                for transaction_type, income_type, amount_used, staff_id,equity_ratio in transactions:
                    consumption = CardConsumption(
                        transaction_type=transaction_type,
                        income_type=income_type,
                        amount_used=amount_used,
                        staff_id=staff_id,
                        equity_ratio=equity_ratio,
                        store_id=store.id,
                        card_package_id=card_package.id if card_package else None,
                        user_id=user.id,
                        product_id=product.id,
                        consumption_date=datetime.now(),
                        order_id=new_order.id,
                        card_type=card_package.card_type if card_package else None
                    )
                    db.session.add(consumption)

            # 创建订单员工关系记录
            order_staff = OrderStaff(
                order_id=new_order.order_id,
                staff_id=staff.user_id,  # 使用预先查询的员工信息
                staff_role='理发师'
            )
            db.session.add(order_staff)

            # 更新卡包余额
            if card_package:
                if card_package.card_type == 'per_use':
                    card_package.remaining_amount -= 1
                elif card_package.card_type == 'comprehensive' or \
                    (card_package.card_type == 'default' and data.get('payment_method') == 'card'):
                    # 计算综合卡或默认卡(会员卡支付)消费金额
                    card_package.remaining_amount = card_package.remaining_amount - actual_amount
                # 默认卡包且非会员卡支付不需要更新余额
                db.session.add(card_package)
            # 提交所有更改
            db.session.commit()

            # 重新查询完整订单数据
            result = db.session.query(
                Order, Store, User.name.label('customer_name'), User.phone.label('customer_phone')
            ).join(
                Store, Order.store_id == Store.store_id
            ).join(
                User, Order.customer_id == User.user_id
            ).filter(
                Order.order_id == new_order.order_id
            ).first()

            if not result:
                raise ValueError('订单创建失败，请检查店铺和用户信息')

            order, store, customer_name, customer_phone = result
            order_data = order.to_dict()
            order_data['store'] = store.to_dict()
            order_data['customer'] = {
                'name': customer_name,
                'phone': customer_phone
            }
            
            return {
                'status': 'success',
                'message': '订单创建成功',
                'data': order_data
            }, 201

        except Exception as e:
            import traceback
            print(f"订单创建失败: {str(e)}")
            print("异常详情:")
            print(traceback.format_exc())
            
            db.session.rollback()
            return {
                'status': 'error',
                'message': f'订单创建失败: {str(e)}'
            }, 500

    @api.doc('更新订单信息')
    @api.marshal_with(order_detail_response)
    @token_required
    def put(self, order_id):
        """更新订单信息"""
        order = Order.query.get_or_404(order_id)
        data = request.get_json()
        
        # 更新订单信息
        if 'status' in data:
            order.status = data['status']
        if 'payment_method' in data:
            order.payment_method = data['payment_method']
        if 'remarks' in data:
            order.remarks = data['remarks']
        
        db.session.commit()
        
        return {
            'status': 'success',
            'message': '订单信息更新成功',
            'data': order.to_dict()
        }, 200

    @api.doc('删除订单')
    @api.marshal_with(base_response)
    @token_required
    def delete(self, order_id):
        """删除订单（软删除）"""
        order = Order.query.get_or_404(order_id)
        
        order.is_deleted = True
        db.session.commit()
        
        return {
            'status': 'success',
            'message': '订单删除成功'
        }, 200



def _calculate_transaction_details(payment_method:str,customer: User, product:Product, card_package: CardPackage, staff: User) -> list:
    """计算交易详情,生成收支记录"""
    result = []
    
    # 获取员工提成比例
    staff_store = UserStore.query.filter_by(
        user_id=staff.user_id,
        store_id=card_package.store_id
    ).first()
    
    if not staff_store:
        raise ValueError(f'员工{staff.user_id}在店铺{card_package.store_id}中未找到关联记录')
    
    
    if card_package:
        # 根据卡包类型处理
        if card_package.card_type == 'default' and payment_method != 'card':
            # 默认卡(会员卡支付)：按折扣率计算金额:
            # 默认卡，现金消费、微信、支付宝：按折扣率计算金额
            discounted_price = product.price * (card_package.discount_rate or 1)
            result.append((3, 1, discounted_price,staff.id,None))
            
             # 根据产品上单次的扣费类型(材料费)，计算出扣费金额，添加扣款记录
            deduction_amount = 0
            if product.charge_type and product.charge_value > 0:
                # 计算扣费金额
                deduction_amount = 0
                if product.charge_type == 1:  # 固定金额
                    deduction_amount = product.charge_value
                    result.append((7, 3, deduction_amount,staff.id,None))
                elif product.charge_type == 2:  # 比例
                    deduction_amount = round(discounted_price * (product.charge_value ), 2)
                    result.append((8, 3, deduction_amount,staff.id,None))

            # 添加提成记录（按折扣后金额减去材料费计算）
            commission = round(discounted_price * staff_store.commission_rate, 2)-deduction_amount
            result.append((6, 0, commission,staff.id,None))
                    
            # 计算剩余余额（收入减去支出）
            total_income = discounted_price
            total_expense = commission
            remaining_balance = round(total_income - total_expense, 2)
            
            # 无论余额是正是负，都需要按照股东比例分配或分摊
            # 查询店铺中有股份的用户（排除平台股东）
            store_shareholders = db.session.query(UserStore, User.id).join(
                User, UserStore.user_id == User.user_id
            ).filter(
                UserStore.store_id == card_package.store_id,
                UserStore.equity_ratio > 0,
                UserStore.role != 'platform_shareholder',
                User.is_deleted == False
            ).all()
            
            # 分配给普通股东的总金额
            distributed_amount = 0
            
            # 为每个股东生成分配记录
            for shareholder,staff_id in store_shareholders:
                if shareholder.equity_ratio > 0:
                    # 直接使用数据库中的股份比例计算
                    shareholder_amount = round(remaining_balance * shareholder.equity_ratio, 2)
                    
                    # 无论金额是正是负都记录
                    # 如果是正数，表示分红；如果是负数，表示分摊成本
                    amount = shareholder_amount 
                    # 创建消费记录（店铺支出或收入）
                    result.append((9, 0, amount,staff_id,shareholder.equity_ratio))
                    distributed_amount += shareholder_amount
            
            # 计算分配后剩余的金额
            platform_remaining = round(remaining_balance - distributed_amount, 2)
            
            # 无论是盈利还是亏损，剩余部分都分配给平台股东
            # 查询平台股东
            platform_shareholders = db.session.query(UserStore, User.id).join(
                User, UserStore.user_id == User.user_id
            ).filter(
                UserStore.store_id == card_package.store_id,
                UserStore.role == 'platform_shareholder',
                User.is_deleted == False
            ).all()
                
            if platform_shareholders:
                # 如果有多个平台股东，按照他们的股份比例分配
                platform_total_equity = sum(ps[0].equity_ratio for ps in platform_shareholders)
                
                for platform_shareholder,staff_id in platform_shareholders:
                    if platform_total_equity > 0:
                        # 按比例分配平台股东的份额
                        platform_share = round(platform_remaining * (platform_shareholder.equity_ratio / platform_total_equity), 2)
                    else:
                        # 如果没有设置股份比例，平均分配
                        platform_share = round(platform_remaining / len(platform_shareholders), 2)
                            
                    # 确定收支类型
                    # 如果是负数，记为收入（分摊成本）
                    amount = platform_share  # 取绝对值记录
                    # 创建平台股东分配记录
                    result.append((10, 0, amount,staff_id,platform_shareholder.equity_ratio))
        elif card_package.card_type == 'default' and payment_method == 'card':
            # 默认卡(会员卡支付)：按折扣率计算金额:
            # 默认卡：按折扣率计算金额
            discounted_price = product.price * (card_package.discount_rate or 1)
            result.append((4, 3, discounted_price,staff.id,None))
            # 添加提成记录（按折扣后金额计算）
            commission = round(discounted_price * staff_store.commission_rate, 2)
            if commission > 0:
                result.append((5, 0, commission,staff.id,None))
            
            # 根据产品上单次的扣费类型，计算出扣费金额，添加扣款记录
            if product.charge_type and product.charge_value > 0:
                # 计算扣费金额
                deduction_amount = 0
                if product.charge_type == 1:  # 固定金额
                    deduction_amount = product.charge_value
                    result.append((7, 1, deduction_amount,staff.id,None))
                elif product.charge_type == 2:  # 比例
                    deduction_amount = round(discounted_price * (product.charge_value ), 2)
                    result.append((8, 1, deduction_amount,staff.id,None))
        
        elif card_package.card_type == 'comprehensive':
            # 计算折扣后价格
            discounted_price = product.price * (card_package.discount_rate or 0)
            # 从卡包扣除折扣后金额
            result.append((4, 3, discounted_price,staff.id,None))
            # 计算提成：折扣后价格乘以员工提成比例
            commission = round(discounted_price * staff_store.commission_rate, 2)
            if commission > 0:
                result.append((5, 0, commission,staff.id,None))

            # 根据产品上单次的扣费类型，计算出扣费金额，添加扣款记录
            if product.charge_type and product.charge_value > 0:
                # 计算扣费金额
                deduction_amount = 0
                if product.charge_type == 1:  # 固定金额
                    deduction_amount = product.charge_value
                    result.append((7, 1, deduction_amount,staff.id,None))
                elif product.charge_type == 2:  # 比例
                    deduction_amount = round(discounted_price * (product.charge_value ), 2)
                    result.append((8, 1, deduction_amount,staff.id,None))

        
        elif card_package.card_type == 'per_use':
            # 按次计费卡：计算单次价格
            if not card_package.recharge_amount or not card_package.total_amount:
                raise ValueError('按次计费卡必须设置充值金额和总次数')
            per_use_price = round(card_package.recharge_amount / card_package.total_amount, 2)
            result.append((4, 3, per_use_price,staff.id,None))
            commission = round(per_use_price * staff_store.commission_rate, 2)
            if commission > 0:
                result.append((6, 0, commission,staff.id,None))
            # 根据产品上单次的扣费类型，计算出扣费金额，添加扣款记录
            if product.charge_type and product.charge_value > 0:
                # 计算扣费金额
                deduction_amount = 0
                if product.charge_type == 1:  # 固定金额
                    deduction_amount = product.charge_value
                    result.append((7, 1, deduction_amount,staff.id,None))
                elif product.charge_type == 2:  # 比例
                    deduction_amount = round(per_use_price * (product.charge_value ), 2)
                    result.append((8, 1, deduction_amount,staff.id,None))
    

    return result